#!/usr/bin/env nu
# Info: Script to run Provisioning
# Author: JesusPerezLorenzo
# Release: 1.0.4
# Date: 6-2-2024

#use std  # assert
use std log

use lib_provisioning *

use servers/ssh.nu *
use infras/utils.nu *

use env.nu *

use infras *

use main_provisioning/ops.nu provisioning_infra_options

# - > Help on Infra
export def "main help" [
  --src: string = ""
  --notitles       # not tittles
  --out: string    #  Print Output format: json, yaml, text (default)
] {
  if $notitles == null or not $notitles { show_titles }
  ^($env.PROVISIONING_NAME) "-mod" "infra" "--help"
  if ($out | is-not-empty) { $env.PROVISIONING_NO_TERMINAL = false }
  print (provisioning_infra_options)
  if not $env.PROVISIONING_DEBUG { end_run "" }
}

# >  Infras with Tasks and Services for servers
def main [
  ...args: string  # Other options, use help to get info
  --iptype: string = "public" # Ip type to connect
  -v               # Show version
  -i               # Show Info
  --version (-V)   # Show version with title
  --info (-I)      # Show Info  with title
  --about (-a)     # Show About
  --infra (-i): string  # Infra directory
  --infras: string # Infras list names  separated by commas
  --settings (-s): string # Settings path
  --iptype: string = "public" # Ip type to connect
  --serverpos (-p): int   # Server position in settings
  --check (-c)     # Only check mode no servers will be created
  --yes (-y)       # Confirm task
  --wait (-w)      # Wait servers to be created
  --select: string # Select with taskservice  as option
  --onsel: string  # On selection: e (edit) | v (view) | l (list)
  --debug (-x)     # Use Debug mode
  --xm             # Debug with PROVISIONING_METADATA
  --xc             # Debuc for taskservice and services locally PROVISIONING_DEBUG_CHECK
  --xr             # Debug for remote servers PROVISIONING_DEBUG_REMOTE
  --xld            # Log level with DEBUG PROVISIONING_LOG_LEVEL=debug
  --nc             # Not clean working settings
  --metadata       # Error with metadata (-xm)
  --notitles       # Do not show banner titles
  --helpinfo (-h)  # For more details use options "help" (no dashes)
  --out: string    #  Print Output format: json, yaml, text (default)
]: nothing -> nothing {
  if ($out | is-not-empty) {
    $env.PROVISIONING_OUT = $out
    $env.PROVISIONING_NO_TERMINAL = true
  }
  provisioning_init $helpinfo "infra" $args
  if $version or $v { ^$env.PROVISIONING_NAME -v ; exit }
  if $info or $i { ^$env.PROVISIONING_NAME -i ; exit }
  if $about {
    #use defs/about.nu [ about_info ]
    _print (get_about_info)
    exit
  }
  if $debug { $env.PROVISIONING_DEBUG = true }
  if $metadata { $env.PROVISIONING_METADATA = true }
  # for $arg in $args { print $arg  }
  let task = if ($args | length) > 0 { ($args| get 0) } else { "" }
  let ops = if ($args | length) > 1 { ($args | skip 1 | str join " ") } else { "" }
  let infras_list = if $infras != null {
    $infras | split row ","
  } else if ($ops | split row " " | get -o 0 | str contains ",") {
    ($ops | split row " " | get -o 0 | split row ",")
  } else if ($infra | is-not-empty) {
    [ $infra ]
  } else { [] }
  let ops = if ($ops | split row " " | get -o 0 | str contains ",") {
    ($ops | str replace ($ops | split row " " | get -o 0 ) "")
  } else { $ops }
  let name = if ($ops | str starts-with "-") { "" } else { ($ops | split row "-" | find -v -r "^--" | get -o 0 | default "" | str trim) }
  match $task {
    "h" | "help" => {
      # Redirect to main categorized help system
      exec ($env.PROVISIONING_NAME) "help" "infrastructure" "--notitles"
    },
    "ssh" => {
      #use servers/ssh.nu *
      #use utils/settings.nu *
      #let curr_settings = (find_get_settings --infra $infra --settings $settings)
      #server_ssh $curr_settings "" "pub"
      exec ($env.PROVISIONING_NAME) "-mod" "server" "status" ...($ops | split row " ") --notitles
    }
    "c" | "create" => {
      let outfile = ""
      on_create_infras  $infras_list $check $wait $outfile $name $serverpos
    }
    "d" | "delete" => {
      if not $yes or not (($env.PROVISIONING_ARGS? | default "") | str contains "--yes")  {
        _print $"Run (_ansi red_bold)delete infras(_ansi reset) (_ansi cyan_bold)($infras_list)(_ansi reset) type (_ansi green_bold)yes(_ansi reset) ? "
        let user_input = (input --numchar 3)
        if $user_input != "yes" and $user_input != "YES"  {
          exit 1
        }
      }
      let keep_storage = false
      on_delete_infras  $infras_list $keep_storage $wait $name $serverpos
    }
    "g" | "generate" => {
      let outfile = ""
      on_generate_infras  $infras_list $check $wait $outfile $name $serverpos
    }
    "t" | "taskserv" => {
      let hostname = if ($ops | str starts-with "-") { "" } else { ($ops | split row "-" | find -v -r "^--" | get -o 1 | default "" | str trim) }
      on_taskserv_infras $infras_list $check $name $hostname --iptype $iptype
    }
    "cost" | "price" => {
      let match_host = if ($name | str starts-with "-") {
        ""
      } else {
        $name
      }
      infras_walk_by $infras_list $match_host $check false
    }
    "list" => {
      #use defs/lists.nu on_list
      on_list "infras" ($onsel | default "") ""
    },
    _ => {
      invalid_task "infra" $task --end
    },
  }
  if not $env.PROVISIONING_DEBUG { end_run "" }
}
